package com.mdp.lcode.ctrl;

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.mdp.Util;
import com.mdp.core.SpringContextUtils;
import com.mdp.core.utils.BaseUtils;
import com.mdp.core.utils.ObjectTools;
import com.mdp.lcode.entity.*;
import com.mdp.lcode.service.DbTableService;
import com.mdp.lcode.service.FormDefService;
import com.mdp.lcode.service.FormFieldService;
import com.mdp.meta.client.entity.ExtInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mdp.core.entity.Result;
import com.mdp.core.query.QueryTools;
import com.mdp.core.entity.LangTips;
import com.mdp.core.err.BizException;
import com.mdp.safe.client.entity.User;
import com.mdp.safe.client.utils.LoginUtils;
import com.mdp.swagger.ApiEntityParams;
import springfox.documentation.annotations.ApiIgnore;

import com.mdp.lcode.service.FormDataService;

@RestController
@RequestMapping(value="/**/lcode/formData")
@Api(tags={"表单数据表-操作接口"})
public class FormDataController {
	
	static Logger logger =LoggerFactory.getLogger(FormDataController.class);
	
	@Autowired
	private FormDataService formDataService;


	@Autowired
	private FormFieldService formFieldService;


	private DynamicRoutingDataSource dataSourceService;


	@Autowired
	private DbTableService dbTableService;

	@ApiOperation( value = "表单数据表-查询列表",notes=" ")
	@ApiEntityParams(FormData.class)
	@ApiResponses({
		@ApiResponse(code = 200,response=FormData.class,message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'错误码'},total:总记录数,data:[数据对象1,数据对象2,...]}")
	})
	@RequestMapping(value="/list",method=RequestMethod.GET)
	public Result listFormData(@ApiIgnore @RequestParam Map<String,Object> params){
		try {
			String formId= (String) params.get("formId");
			if(ObjectTools.isEmpty(formId)){
				return Result.error("formId-required","表单编号不能为空");
			}

			FormDefVo formDefVo=formFieldService.getFormFieldFromCache(formId);
			if(formDefVo==null){
				return Result.error("formDef-0","表单不存在");
			}
			User user=LoginUtils.getCurrentUserInfo();
			QueryWrapper<FormData> qw = QueryTools.initQueryWrapper(FormData.class , params);
			FormQx formQx=formDefVo.getFormQx();

			if(formQx!=null){
				if("0".equals(formQx.getOthQuery())){
					qw.eq("cuserid",user.getUserid());
				}else{
					boolean roleCheckOk=false;
					boolean useridCheckOk=false;
					boolean deptidCheckOk=false;
					if(ObjectTools.isNotEmpty(formQx.getQryRoleids())){
						if(LoginUtils.hasAnyRoles(formQx.getQryRoleids().split(","))){
							roleCheckOk=true;
						}
					}
					if(ObjectTools.isNotEmpty(formQx.getQryUserids())){
						if(Arrays.stream(formQx.getQryUserids().split(",")).filter(k->user.getUserid().equals(k)).findAny().isPresent()){
							useridCheckOk=true;
						}
					}

					if(ObjectTools.isNotEmpty(formQx.getQryDeptids())){
						if(Arrays.stream(formQx.getQryDeptids().split(",")).filter(k->user.getDeptid().equals(k)).findAny().isPresent()){
							deptidCheckOk=true;
						}
					}
					boolean allowCheckOk=roleCheckOk||useridCheckOk||deptidCheckOk;
					boolean notAllow=false;
					if(ObjectTools.isNotEmpty(formQx.getNqRoleids())){
						if(LoginUtils.hasAnyRoles(formQx.getNqRoleids().split(","))){
							notAllow=true;
						}
					}
					if(ObjectTools.isNotEmpty(formQx.getNqUserids())){
						if(Arrays.stream(formQx.getNqUserids().split(",")).filter(k->user.getUserid().equals(k)).findAny().isPresent()){
							notAllow=true;
						}
					}

					if(ObjectTools.isNotEmpty(formQx.getNqDeptids())){
						if(Arrays.stream(formQx.getNqDeptids().split(",")).filter(k->user.getDeptid().equals(k)).findAny().isPresent()){
							notAllow=true;
						}
					}
					//禁止条款优先级最高
					//如果是被禁止的任一条款满足条件，则全部禁止
					if( notAllow ){
						return Result.error("no-qx-query","无权限查询");
					}else if(!allowCheckOk){//如果被允许的任意条款满足，则允许
						if(ObjectTools.isNotEmpty(formQx.getQryRoleids())||ObjectTools.isNotEmpty(formQx.getQryDeptids())||ObjectTools.isNotEmpty(formQx.getQryUserids())){
							return Result.error("no-qx-query","无权限查询");
						}
					}

				}
			}
			IPage page=QueryTools.initPage(params);
			List<Map<String,Object>> datas=new ArrayList<>();
			FormDef formDef=formDefVo.getFormDef();
			if("2".equals(formDefVo.getFormDef().getDataType()) ||"3".equals(formDefVo.getFormDef().getDataType())){
				return dbTableService.list(formDef, formDefVo.getFormFields(),params);
			}else{
				qw.eq("branch_id",user.getBranchId());
				datas = formDataService.selectListMapByWhere(page,qw,params);
			}

			return Result.ok("query-ok","查询成功").setData(datas).setTotal(page.getTotal());
		}catch (BizException e) {
			return Result.error(e);
		}catch (Exception e) {
			return Result.error(e);
		}
	}
	

	@ApiOperation( value = "表单数据表-新增",notes=" ")
	@ApiResponses({
		@ApiResponse(code = 200,response=FormData.class,message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")
	}) 
	@RequestMapping(value="/add",method=RequestMethod.POST)
	public Result addFormData(@RequestBody Map<String,Object> params) {
		FormData formData=BaseUtils.fromMap(params,FormData.class);
		if(StringUtils.isEmpty(formData.getFstate())) {
			formData.setFstate("0");
		}
		if(ObjectTools.isEmpty(formData.getFormId())){
			return Result.error("formId-required","表单编号不能为空");
		}
		FormDefVo formDefVo=formFieldService.getFormFieldFromCache(formData.getFormId());
		if(formDefVo==null){
			throw new BizException("formDef-0","表单不存在");
		}
		List<FormField> formFields=formDefVo.getFormFields();

		User user=LoginUtils.getCurrentUserInfo();
		formData.setUserid(user.getUserid());
		formData.setBranchId(user.getBranchId());
		formData.setCuserid(user.getUserid());
		formData.setCusername(user.getUsername());
		formData.setDeptid(user.getDeptid());
		formData.setDeptName(user.getDeptName());
		formData.setCtime(new Date());
		formData.setLtime(new Date());
		FormDef formDef=formDefVo.getFormDef();
		if("2".equals(formDef.getDataType())||"3".equals(formDef.getDataType())){
			 dbTableService.saveOrUpdate(formDef,formFields,params);
			return Result.ok();
		}

		/**
		 * 必输项检查
		 */
		Map<String,Object> formDataMap=BaseUtils.toMap(formData);
		for (FormField field : formFields.stream().filter(k-> !"row".equals(k.getExtType())&&!"card".equals(k.getExtType()) && !"tabs".equals(k.getExtType())).collect(Collectors.toList())) {
			Object pkValue= formDataMap.get(field.getIdCamel());
			if("1".equals(field.getReq()) && ObjectTools.isEmpty(pkValue)){
				return Result.error("field-required","%s不能为空",field.getTitle());
			}
		}
		String bizKey=formDataService.createBizKey(formDefVo,formData);
		if(ObjectTools.isNotEmpty(bizKey) && formDataService.count(QueryTools.initQueryWrapper(FormData.class).eq("biz_key",bizKey).eq("form_id",formData.getFormId()))>0){
			return Result.error("biz-key-exists","%s已存在",bizKey);
		};
		formData.setId(formDataService.createKey("id"));
		formData.setBizKey(ObjectTools.isNotEmpty(bizKey)?bizKey:formData.getId());
		formDataService.save(formData);
         return Result.ok("add-ok","添加成功！");
	}



	@ApiOperation( value = "表单数据表-删除",notes=" ")
	@ApiResponses({
		@ApiResponse(code = 200, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'}}")
	}) 
	@RequestMapping(value="/del",method=RequestMethod.POST)
	public Result delFormData(@RequestBody FormData formData){
		formDataService.removeById(formData);
        return Result.ok("del-ok","删除成功！");
	}

	@ApiOperation( value = "表单数据表-修改",notes=" ")
	@ApiResponses({
		@ApiResponse(code = 200,response=FormData.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")
	}) 
	@RequestMapping(value="/edit",method=RequestMethod.POST)
	public Result editFormData(@RequestBody Map<String,Object> params) {
		FormData formData=BaseUtils.fromMap(params,FormData.class);
		if(ObjectTools.isEmpty(formData.getFormId())){
			throw new BizException("formId-0","表单编号不能为空");
		}
		FormDefVo formDefVo=formFieldService.getFormFieldFromCache(formData.getFormId());
		if(formDefVo==null){
			throw new BizException("formDef-0","表单不存在");
		}
		List<FormField> formFields=formDefVo.getFormFields();
		/**
		 * 必输项检查
		 */
		for (FormField field : formFields) {
			Object pkValue= params.get(field.getIdCamel());
			if("1".equals(field.getReq()) && ObjectTools.isEmpty(pkValue)){
				return Result.error("field-required","%s不能为空",field.getTitle());
			}
		}
		FormDef formDef=formDefVo.getFormDef();
		if("2".equals(formDef.getDataType())||"3".equals(formDef.getDataType())){
			dbTableService.saveOrUpdate(formDef,formFields,params);
			return Result.ok();
		}
		if(ObjectTools.isEmpty(formData.getId())){
			return Result.error("id-0","主键不能为空");
		}
		formData.setLtime(new Date());
		if(formData.getCtime()==null) {
			formData.setCtime(new Date());
		}
		User user=LoginUtils.getCurrentUserInfo();
		formData.setUserid(user.getUserid());
		formData.setLtime(new Date());

		if(StringUtils.isEmpty(formData.getFstate())) {
			formData.setFstate("0");
		}
		FormData formDataDb=formDataService.getById(formData.getId());
		if(formDataDb==null){
			return Result.error("data-0","数据已不存在");
		}
		String bizKey= formDataService.createBizKey(formDefVo,formData);
		formData.setBizKey(ObjectTools.isNotEmpty(bizKey)?bizKey:formDataDb.getId());
		if(ObjectTools.isNotEmpty(bizKey) && !bizKey.equals(formDataDb.getBizKey())){
			if(formDataService.count(QueryTools.initQueryWrapper(FormData.class).eq("biz_key",bizKey).eq("form_id",formData.getFormId()))>0){
				return Result.error("biz-key-exists","%s已存在",bizKey);
			};
		}
		formDataService.updateById(formData);
        return Result.ok("edit-ok","修改成功！");
	}

    @ApiOperation( value = "表单数据表-批量修改某些字段",notes="")
    @ApiEntityParams( value = FormData.class, props={ }, remark = "表单数据表", paramType = "body" )
	@ApiResponses({
			@ApiResponse(code = 200,response=FormData.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")
	})
	@RequestMapping(value="/editSomeFields",method=RequestMethod.POST)
	public Result editSomeFields( @ApiIgnore @RequestBody Map<String,Object> params) {
        try{
            User user= LoginUtils.getCurrentUserInfo();
            formDataService.editSomeFields(params);
            return Result.ok("edit-ok","更新成功");
        }catch (BizException e) {
            logger.error("",e);
            return Result.error(e);
        }catch (Exception e) {
            logger.error("",e);
            return Result.error(e);
        }
	}

	@ApiOperation( value = "表单数据表-批量删除",notes=" ")
	@ApiResponses({
		@ApiResponse(code = 200, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'}")
	}) 
	@RequestMapping(value="/batchDel",method=RequestMethod.POST)
	public Result batchDelFormData(@RequestBody List<FormData> formDatas) {
	    User user= LoginUtils.getCurrentUserInfo();
        try{ 
            if(formDatas.size()<=0){
                return Result.error("formData-batchDel-data-err-0","请上送待删除数据列表");
            }
             List<FormData> datasDb=formDataService.listByIds(formDatas.stream().map(i-> i.getId() ).collect(Collectors.toList()));

            List<FormData> can=new ArrayList<>();
            List<FormData> no=new ArrayList<>();
            for (FormData data : datasDb) {
                if(true){
                    can.add(data);
                }else{
                    no.add(data);
                } 
            }
            List<String> msgs=new ArrayList<>();
            if(can.size()>0){
                formDataService.removeByIds(can);
                msgs.add(LangTips.transMsg("del-ok-num","成功删除%s条数据.",can.size()));
            }
    
            if(no.size()>0){ 
                msgs.add(LangTips.transMsg("not-allow-del-num","以下%s条数据不能删除:【%s】",no.size(),no.stream().map(i-> i.getId() ).collect(Collectors.joining(","))));
            }
            if(can.size()>0){
                 return Result.ok(msgs.stream().collect(Collectors.joining()));
            }else {
                return Result.error(msgs.stream().collect(Collectors.joining()));
            } 
        }catch (BizException e) { 
           return Result.error(e);
        }catch (Exception e) {
            return Result.error(e);
        }


	} 

	@ApiOperation( value = "表单数据表-根据主键查询一条数据",notes=" ")
     @ApiResponses({
            @ApiResponse(code = 200,response=FormData.class, message = "{tips:{isOk:true/false,msg:'成功/失败原因',tipscode:'失败时错误码'},data:数据对象}")
    })
    @RequestMapping(value="/queryById",method=RequestMethod.GET)
    public Result queryById(FormData formData) {
        FormData data = (FormData) formDataService.getById(formData);
        return Result.ok().setData(data);
    }

	/**
	 * 流程审批过程中回调该接口，更新业务数据
	 * 如果发起流程时上送了restUrl，则无论流程中是否配置了监听器都会在流程发生以下事件时推送数据过来
	 * eventName: PROCESS_STARTED 流程启动完成 全局
	 *            PROCESS_COMPLETED 流程正常结束 全局
	 *            PROCESS_CANCELLED 流程删除 全局
	 *            create 人工任务启动
	 *            complete 人工任务完成
	 *            assignment 人工任务分配给了具体的人
	 *            delete 人工任务被删除
	 *
	 * 其中 create/complete/assignment/delete事件是需要在模型中人工节点上配置了委托代理表达式 ${taskBizCallListener}才会推送过来。
	 * 在人工任务节点上配置 任务监听器  建议事件为 complete,其它assignment/create/complete/delete也可以，一般建议在complete,委托代理表达式 ${taskBizCallListener}
	 *
	 * @param flowVars {flowBranchId,agree,procInstId,assignee,actId,taskName,mainTitle,branchId,bizKey,commentMsg,eventName,modelKey} 等
	 * @return 如果tips.isOk==false，将影响流程提交
	 **/
	@RequestMapping(value="/processApprova",method=RequestMethod.POST)
	public Map<String,Object> processApprova( @RequestBody Map<String,Object> flowVars){
		try{
			this.formDataService.processApprova(flowVars);
			logger.debug("procInstId====="+flowVars.get("procInstId"));
			return Result.ok();
		}catch (BizException e) {
			logger.error("执行异常",e);
			return Result.error(e);
		}catch (Exception e) {
			logger.error("执行异常",e);
			return Result.error(e.getMessage());
		}
	}
}
